【ARM Linux 系统稳定性分析入门及渐进 4

您所在的位置:网站首页 arm linux软件 【ARM Linux 系统稳定性分析入门及渐进 4

【ARM Linux 系统稳定性分析入门及渐进 4

#【ARM Linux 系统稳定性分析入门及渐进 4 | 来源: 网络整理| 查看: 265

文章目录 1.1 RT-Thread 的系统栈1.2 RT-Thread 进程栈1.2.1 线程栈溢出检查

1.1 RT-Thread 的系统栈

系统栈底的值如果是 gcc 编译器,一般会在系统链接脚本 link.lds 中设置, 如下配置系统栈的大小为 1K; _system_stack_size = 0x400;

在系统启动阶段一般都是先通过汇编代码进行部分处理,比如data 段中的数据copy, 及 bss 段的清零,然后一般会跳转到C代码,在使用C代码之前需要设置好栈的地址,我们知道C代码实现的函数通过反汇编可以看到:在函数之间的调用处会保存一些关键信息,比如 PC/LR/SP/FP,及相关参数到栈中,所以在跳转到C代码之前一定要配置好栈的地址。系统栈地址的配置一般都是在汇编阶段给 SP指针赋值,在 RT-Thread 中BSP目录下一般会有个名叫 startup.s 的文件,在该文件中的会对 SP 进行赋值:

ldr sp, =_estack

_estack 即为栈底(栈底是高地址)的位置,该值会在连接脚本中赋值, 如下:

.stack : { . = ALIGN(4); __sstack = .; . = . + system_stack_size; . = ALIGN(4) _estack = .; }> RAM

在 RT-Thread 中需要知道系统栈(中断栈)与进程栈不是一回事

1.2 RT-Thread 进程栈

在多线程系统中,每个线程都是独立的、互不干扰的,所以要为每个线程都分配独立的栈空间。这个栈空间可以是:

一个预先定义好的全局数组,定义线程栈的示例代码如下: ALIGN(RT_ALIGN_SIZE) rt_uint8_t thread1_stack[512]; rt_uint8_t thread2_stack[1024]; 也可以是动态分配的一段内存空间: thread->stack_addr = (void *)RT_KERNEL_MALLOC(stack_size); static rt_err_t _thread_init(struct rt_thread *thread, ...) { ... /* stack init */ thread->stack_addr = stack_start; thread->stack_size = stack_size; /* init thread stack */ rt_memset(thread->stack_addr, '#', thread->stack_size); ...

从上面可以看到 task 初始化的时候会将栈空间填入'#',

1.2.1 线程栈溢出检查

OS 在调度时 (rt_scheudle) 主动检查栈是否溢出:

线程栈底部预留内存是不是有被修改;sp是否超出线程栈范围 栈增长方向不同,略有区别,原理一样,ARM 架构通常使用向下增长方式。 #ifdef RT_USING_OVERFLOW_CHECK static void _rt_scheduler_stack_check(struct rt_thread *thread) { RT_ASSERT(thread != RT_NULL); #ifdef ARCH_CPU_STACK_GROWS_UPWARD if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' || #else if (*((rt_uint8_t *)thread->stack_addr) != '#' || #endif /* ARCH_CPU_STACK_GROWS_UPWARD */ (rt_ubase_t)thread->sp stack_addr || (rt_ubase_t)thread->sp > (rt_ubase_t)thread->stack_addr + (rt_ubase_t)thread->stack_size) { rt_ubase_t level; rt_kprintf("thread:%s stack overflow\n", thread->name); level = rt_hw_interrupt_disable(); while (level); } ... ... } #endif /* RT_USING_OVERFLOW_CHECK */ stack frameaddr栈底: thread->stack_addrlowstack size栈顶:thread->stack_addr + thread->stack_sizehigh


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3